package com.collabscm.waf.domain.repository.support;

import java.io.Serializable;

import javax.persistence.EntityManager;

import com.collabscm.waf.domain.model.DomainObject;
import com.collabscm.waf.domain.repository.DatabaseRepository;
import com.collabscm.waf.solution.logging.Logger;
import com.collabscm.waf.solution.logging.LoggerFactory;

/**
 * DomainDao的工厂类，为了获得对应GenericDao的实例。
 *
 * @author Zeng Raoxing
 */
public class DomainRepositoryFactory {
	private static Logger logger = LoggerFactory.getLogger(DomainRepositoryFactory.class);
	/**
	 * 创建一个DomainDao的实例
	 * 
	 * @param <T>  实体类
     * @param <PK> 主键类
	 * @return 一个新创建的DomainDao实例
	 */
	public static <T extends DomainObject, PK extends Serializable> DatabaseRepository<T, PK> createGenericDao(Class<T> clazz) {
		DomainRepository<T, PK> genericDao = new DomainRepository<T, PK>(clazz);
		genericDao.setEntityManager(getEntityManager());
		logger.debug("创建了{}的DatabaseDao实例", genericDao.getMappingClass());
		return genericDao;
	}
	
	/**
	 * 得到系统中统一的EntityManager
	 */
	public static EntityManager getEntityManager() {
		return emp.getEntityManager();
	}
	
	private static EntityManagerProvider emp;
	
	/**
	 * DomainDaoFactory的EntityManagerProvider类，是为了提供EntityManager.
	 *
	 * @author Zeng Raoxing
	 */
	public static abstract class EntityManagerProvider {
		
		public EntityManagerProvider() {
			if(emp == null) {
				emp = this;
				logger.trace("设置了EntityManagerProvider:{}", emp);
			} else {
				if(emp != this) {
					logger.warn("DomainDaoFactory的EntityManagerProvider不能重复实例化。" + emp + ":" + this);
				}
			}
		}
		
		/**
		 * 得到对应的EntityManager对象
		 */
		protected abstract EntityManager getEntityManager();
		
	}

}
